﻿#region [===== Using =====]
using System;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
#endregion

namespace TPG.SharePoint.Workflow
{
    public partial class TaskData
    {
        class TaskDataDescriptor
            : CustomTypeDescriptor
        {
            #region [===== Fields =====]
            TaskData _taskData = null;
            #endregion

            #region [===== Constructors =====]
            public TaskDataDescriptor(ICustomTypeDescriptor parent,
                TaskData taskData)
                : base(parent)
            {
                _taskData = taskData;
            }
            #endregion

            #region [===== Public methods =====]
            public override PropertyDescriptorCollection GetProperties()
            {
                List<PropertyDescriptor> descriptors = new List<PropertyDescriptor>();
                foreach (object key in _taskData._taskData.Keys)
                {
                    descriptors.Add(
                        new TaskPropertyDescriptor(key, _taskData[key]));
                }
                // Get all the real properties (used for TaskItem static properties)
                foreach(PropertyDescriptor baseDescriptor in base.GetProperties())
                {
                    descriptors.Add(baseDescriptor);
                }
                return new PropertyDescriptorCollection(descriptors.ToArray());
            }
            #endregion
        }

        class TaskPropertyDescriptor
            : PropertyDescriptor
        {
            #region [===== Fields =====]
            private object _key;
            private object _originalValue;
            #endregion
            #region [===== Properties =====]
            public override Type ComponentType
            {
                get { return typeof(TaskData); }
            }

            public override bool IsReadOnly
            {
                get { return false; }
            }

            public override Type PropertyType
            {
                get
                {
                    return _originalValue != null ?
                        _originalValue.GetType() : typeof(object);
                }
            }
            #endregion

            #region [===== Constructors =====]
            public TaskPropertyDescriptor(object key, object value)
                 : base(Convert.ToString(key),null)
            {
                _key = key;
                _originalValue = value;
            }
            #endregion

            #region [===== Public methods =====]
            public override bool CanResetValue(object component)
            {
                return true;
            }

            public override object GetValue(object component)
            {
                TaskData taskData = EnsureIsTaskData(component);
                return taskData[_key];
            }

            public override void ResetValue(object component)
            {
                TaskData taskData = EnsureIsTaskData(component);
                taskData[_key] = _originalValue;
            }

            public override void SetValue(object component, object value)
            {
                TaskData taskData = EnsureIsTaskData(component);
                taskData[_key] = value;
            }

            public override bool ShouldSerializeValue(object component)
            {
                EnsureIsTaskData(component);
                return true;
            }
            #endregion

            #region [===== Private methods =====]
            private TaskData EnsureIsTaskData(object component)
            {
                TaskData taskData = component as TaskData;
                if (taskData == null)
                {
                    throw new ArgumentException("Component is not a TaskData object");
                }
                return taskData;
            }
            #endregion
        }
    }
}